package com.tepth.appmanageservice.communicate;

import com.tepth.appmanageservice.core.ClientInfo;
import com.tepth.appmanageservice.core.StaticClass;
import com.tepth.appmanageservice.enums.EnumEvent;
import com.tepth.appmanageservice.interfaces.IAction;
import com.tepth.appmanageservice.interfaces.ICommunicate;
import com.tepth.appmanageservice.protocol.Controller;
import com.tepth.appmanageservice.protocol.packets.Packets;
import com.tepth.appmanageservice.tools.LogTool;

import java.io.IOException;
import java.net.Socket;

public class Communicate implements IAction<EnumEvent>, ICommunicate {
    private static final String TAG = "ͨ通道";
    private Interthreaded _interthreaded;

    private Boolean _isconnected;
    private int _retryWaitTime = 10000;

    public Communicate() {
        this._isconnected = false;
    }

    public Boolean isCommunicate() {
        return this._isconnected && this._interthreaded.isLogin;
    }

    public void send(Packets data) throws IOException {
        this._interthreaded.send(data);
    }

    public void startListener() {
        this._interthreaded = new Interthreaded();
        this._interthreaded.setOnSocketOffEvent(this);
        this._interthreaded.setOnAESReplyEvent(this);

        new CommunicateThread(this._interthreaded) {
            public void Run(Interthreaded interthreaded) {
                String serverDomain = StaticClass.get_config().getServerDomain();
                int servierPort = StaticClass.get_config().getServerPort();
                String logStr = " 域名：" + serverDomain + " 端口：" + servierPort;

                while (true) {
                    try {
                        LogTool.i(TAG, "连接中..." + logStr);
                        interthreaded.setSocket(new Socket(serverDomain, servierPort)); // 应用Server的IP和端口建立Socket对象
                        _isconnected = true;
                        LogTool.i(TAG, "已建立连接！" + logStr);

                        if (ClientInfo.ENCRYPTION && interthreaded.getClient().getN() == null) {
                            publicKeyRequest();
                        } else {
                            login();
                        }
                        interthreaded.listener();
                    } catch (Exception e) {
                        _isconnected = false;
                        interthreaded.isLogin = false;
                    }
                    try {
                        LogTool.i(TAG, "连接中断。" + _retryWaitTime + " 毫秒后重新连接. " + logStr);
                        Thread.sleep(_retryWaitTime);
                        LogTool.i(TAG, "重新连接。");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    @Override
    public void Invoke(EnumEvent arg) {
        switch (arg) {
            case SocketOffEvent:
                this.onSocketOffEvent();
                break;
            case PublicKeyEvent:
                this.onPublicKeyEvent();
                break;
            default:
                break;
        }
    }

    private void login() {
        new CommunicateThread(this._interthreaded) {
            public void Run(Interthreaded interthreaded) {
                while (!interthreaded.isLogin && _isconnected) {
                    try {
                        Packets packets = Controller.getLoginBytes(interthreaded.getClient().getAES_KEYS());
                        interthreaded.send(packets);

                        LogTool.i(TAG, "发送登录指令。  " + packets.getBody());
                    } catch (Exception e) {
                        LogTool.i(TAG, "发送登录指令失败。  " + e.getMessage());
                    }
                    try {
                        LogTool.i(TAG, "等待登录应答。应答超时时间：  " + StaticClass.get_config().getLoginRetryInterval());
                        Thread.sleep(StaticClass.get_config().getLoginRetryInterval());
                    } catch (InterruptedException ignored) {

                    }
                }
            }
        }.start();
    }

    private void publicKeyRequest() {
        new CommunicateThread(this._interthreaded) {
            public void Run(Interthreaded interthreaded) {
                try {
                    Packets packets = Controller.getPublicKeyRequest();
                    interthreaded.send(packets);

                    LogTool.i(TAG, "发送获取公钥包指令。  " + packets.getBody());

                } catch (IOException e) {
                    LogTool.i(TAG, "发送获取公钥包指令失败。  " + e.getMessage());
                }

                try {
                    LogTool.i(TAG, "等待公钥包应答。应答超时时间：  " + StaticClass.get_config().getLoginRetryInterval());
                    Thread.sleep(StaticClass.get_config().getLoginRetryInterval());
                } catch (InterruptedException ignored) {

                }
            }
        }.start();
    }

    private void onPublicKeyEvent() {
        this.login();
    }

    private void onSocketOffEvent() {

    }
}